angular.module("dashboardApp")
.controller('mapsCtrl', function($scope, $timeout, listProcess, mapProcess) {

	$scope.vlist = true;
	$scope.mapList = {};
	$scope.categories = [];
	$scope.tab = 'home';

	$scope.newmap = {
		"center": [],
		"zoom": 1,
		"description": "",
		"markers": [],
		"polygons": [],
		"polylines": [],
		"provinces": [],
		"countries": [],
		"grounds": []
	};
	$scope.markerForm = {};
	$scope.polygonForm = {
		"color": "#E74C3C"
	};
	$scope.polylineForm = {
		"color": "#E74C3C",
		"width": 1,
		"arrow": 0,
		"style": "solid"
	};
	$scope.groundForm = {
		"url": "http://diepdoan.violet.vn/uploads/resources/blog/447/luoc_do_chien_dich_tay_bac_500_01.jpg"
	};

	var designMap, listMap, drawingManager;
	var designMarker = {};
	var designPolygon = null;
	var designPolyline = null;
	var designRectangle = null;
	var designOvelay = null;

	var arrMarkers = []; // Array of added marker
	var arrPolygons = []; // Array of added polygons


	listMap = mapProcess.initListMap();

	designObj = mapProcess.initDesignMap();
	designMap = designObj.map;
	designMarker = designObj.mk;
	drawingManager = designObj.drawer;

	listProcess.getList().then(function(dt) {
		$timeout(function() {
			$scope.$apply(function() {
				$scope.$parent.loadingView = false;
			})
		},500).then(function() {
			mapProcess.resizeMaps();
		});
		$scope.mapList = dt;
	})

	listProcess.getCategories().then(function(dt) {
		parentArr = [];
		childArr = [];
		angular.forEach(dt, function(cat) {
			if(!cat.parent) parentArr.push(cat);
			else {
				cat.name = ' -- ' + cat.name;
				childArr.push(cat);
			}
		});
		
		angular.forEach(parentArr, function(par) {
			$scope.categories.push(par);
			angular.forEach(childArr, function(child) {
				if(child.parent == par._id) {
					$scope.categories.push(child);
				}
			});
		});
	});

	// =========================================================================
	// =========================================================================
	$scope.viewMap = function(id) { 
		map = $scope.mapList[id];
		$scope.mapdescript = map.description;
		mapProcess.viewMap(map); 
	}
	$scope.addMap = function() {
		info = $scope.newmap;
		mapProcess.addMapToDb(info);
	}
	$scope.addMarker = function() {
		mk = {};
		angular.forEach($scope.markerForm, function(m, key) {
			mk[key] = m;
		});
		mk.icon = "";
		mk.radius = mk.radius * 1000;
		$scope.newmap.markers.push(mk);

		mapProcess.addDesignMarker(mk);

	}
	$scope.addPolygon = function() {
		plg = {};
		angular.forEach($scope.polygonForm, function(p, key) {
			plg[key] = p;
		});
		$scope.newmap.polygons.push(plg);
		mapProcess.addDesignPolygon(plg);
		designPolygon.setMap(null);
	}
	$scope.addPolyline = function() {
		pll = {};
		angular.forEach($scope.polylineForm, function(p, key) {
			pll[key] = p;
		});
		if(pll.arrow == 0) pll.arrow = false;
		else pll.arrow = true;

		$scope.newmap.polylines.push(pll);
		mapProcess.addDesignPolyline(pll);
		designPolyline.setMap(null);
	}
	$scope.addGroundOvl = function() {
		go = {};
		angular.forEach($scope.groundForm, function(g, key) {
			go[key] = g;
		});
		$scope.newmap.grounds.push(go);
		mapProcess.addDesignOvelay(go);
		designRectangle.setMap(null);
		designOvelay.setMap(null);
	}
	$scope.removeMarker = function(index) {
		$scope.newmap.markers.splice(index, 1);
		mapProcess.eraseElement(1, index);
	}
	$scope.removePolygon = function(index) {
		$scope.newmap.polygons.splice(index, 1);
		mapProcess.eraseElement(2, index);
	}
	$scope.removePolyline = function(index) {
		$scope.newmap.polylines.splice(index, 1);
		mapProcess.eraseElement(3, index);
	}	
	$scope.removeGroundOvl = function(index) {
		$scope.newmap.grounds.splice(index, 1);
		mapProcess.eraseElement(6, index);
	}

	// =========================================================================
	$scope.$watch('vlist', function() {
		mapProcess.resizeMaps();
	});
	$scope.$watch('tab', function() 
	{
		if($scope.tab == 'polygon') {
			drawingManager.setOptions({
				drawingControl: true,
				drawingControlOptions: {
					position: google.maps.ControlPosition.BOTTOM_RIGHT,
					drawingModes: [google.maps.drawing.OverlayType.POLYGON]
				}				
			});
		}
		else if($scope.tab == 'polyline') {
			drawingManager.setOptions({
				drawingControl: true,
				drawingControlOptions: {
					position: google.maps.ControlPosition.BOTTOM_RIGHT,
					drawingModes: [google.maps.drawing.OverlayType.POLYLINE]
				}				
			});
		}
		else if($scope.tab == 'ground') {
			drawingManager.setOptions({
				drawingControl: true,
				drawingControlOptions: {
					position: google.maps.ControlPosition.BOTTOM_RIGHT,
					drawingModes: [google.maps.drawing.OverlayType.RECTANGLE]
				}				
			});
		}
		else {
			drawingManager.setOptions({
				drawingControl: false
			});
		}

		if($scope.tab == 'marker') {
			designMarker.setVisible(true);
			designMarker.setPosition(designMap.getCenter());
		}
		else {
			designMarker.setVisible(false);
		}

	});

	// =========================================================================
	google.maps.event.addListener(designMap, 'bounds_changed', function() {
		latlng = designMap.getCenter();
		lat = Math.round(latlng.k * 100000) / 100000;
		lng = Math.round(latlng.D * 100000) / 100000;
		$scope.$apply(function() {
			$scope.newmap.center = [lat,lng];
			$scope.newmap.zoom = designMap.getZoom();
		});
		if(!designMap.getBounds().contains(designMarker.getPosition())) {
			designMarker.setPosition(latlng);
			ll = designMarker.getPosition();
			lat = Math.round(ll.k * 100000) / 100000;
			lng = Math.round(ll.D * 100000) / 100000;
			$scope.$apply(function() {
				$scope.markerForm.coordinate = lng + ',' + lat;
			});
		}
	});
	google.maps.event.addListener(designMarker, 'dragend', function() {
		latlng = designMarker.getPosition();
		lat = Math.round(latlng.k * 100000) / 100000;
		lng = Math.round(latlng.D * 100000) / 100000;
		$scope.$apply(function() {
			$scope.markerForm.coordinate = lng + ',' + lat;
		});
	});

	google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
		if(designPolygon) designPolygon.setMap(null);
		designPolygon = polygon;
		path = polygon.getPath();
		strP = ""
		path.forEach(function(ele, index) {
			lat = Math.round(ele.lat() * 100000) / 100000;
			lng = Math.round(ele.lng() * 100000) / 100000;
			strP = strP + lng + ',' + lat + ' ';
		});
		strP = strP.substring(0, strP.length - 1);
		$scope.$apply(function() {
			$scope.polygonForm.coordinate = strP;
		});
	});
	google.maps.event.addListener(drawingManager, 'polylinecomplete', function(polyline) {
		if(designPolyline) designPolyline.setMap(null);
		designPolyline = polyline;
		path = polyline.getPath();
		strP = ""
		path.forEach(function(ele, index) {
			lat = Math.round(ele.lat() * 100000) / 100000;
			lng = Math.round(ele.lng() * 100000) / 100000;
			strP = strP + lng + ',' + lat + ' ';
		});
		strP = strP.substring(0, strP.length - 1);
		$scope.$apply(function() {
			$scope.polylineForm.coordinate = strP;
		});
	});
	google.maps.event.addListener(drawingManager, 'rectanglecomplete', function(rectangle) {
		if(designRectangle) designRectangle.setMap(null);
		designRectangle = rectangle;

		neLat = rectangle.getBounds().getNorthEast().lat();
		neLat = Math.round(neLat * 100000) / 100000;
		neLng = rectangle.getBounds().getNorthEast().lng();
		neLng = Math.round(neLng * 100000) / 100000;
		swLat = rectangle.getBounds().getSouthWest().lat();
		swLat = Math.round(swLat * 100000) / 100000;
		swLng = rectangle.getBounds().getSouthWest().lng();
		swLng = Math.round(swLng * 100000) / 100000;

		$scope.$apply(function() {
			$scope.groundForm.ne = neLat + ',' + neLng;
			$scope.groundForm.sw = swLat + ',' + swLng;
		});
		if(designOvelay) designOvelay.setMap(null);
		designOvelay = new google.maps.GroundOverlay($scope.groundForm.url, rectangle.getBounds(), {opacity: 0.3});
		designOvelay.setMap(designMap);
		// mapProcess.addGroundOvl($scope.groundForm.url, rectangle.getBounds());
	});
	if(designRectangle) {
	google.maps.event.addListener(designRectangle, 'bounds_changed', function(event) {
		alert('dsa');
		neLat = designRectangle.getBounds().getNorthEast().lat();
		neLat = Math.round(neLat * 100000) / 100000;
		neLng = designRectangle.getBounds().getNorthEast().lng();
		neLng = Math.round(neLng * 100000) / 100000;
		swLat = designRectangle.getBounds().getSouthWest().lat();
		swLat = Math.round(swLat * 100000) / 100000;
		swLng = designRectangle.getBounds().getSouthWest().lng();
		swLng = Math.round(swLng * 100000) / 100000;

		$scope.$apply(function() {
			$scope.groundForm.nw = neLat + ',' + neLng;
			$scope.groundForm.sw = swLat + ',' + swLng;
		});
		if(designOvelay) designOvelay.setMap(null);
		designOvelay = new google.maps.GroundOverlay($scope.groundForm.url, rectangle.getBounds(), {opacity: 0.1});
		designOvelay.setOpacity(0.2);
		designOvelay.setMap(designMap);
		// mapProcess.addGroundOvl($scope.groundForm.url, rectangle.getBounds());
	})}
})
.factory('listProcess', function($http, BASE_URL) {
	return {
		getList: function() {
			return $http.post(BASE_URL + 'dashboard_api/map/getmaps').then(function(prm) {
				return prm.data;
			});
		},
		getCategories: function() {
			return $http.post(BASE_URL + 'dashboard_api/category/getcatslist').then(function(prm) {
				return prm.data;
			});
		}
	}
})
.factory('mapProcess', function($http, $timeout, BASE_URL) 
{
	var myStyle = [{"featureType":"road","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"administrative","elementType":"geometry","stylers":[{"visibility":"on"},{"weight":0.8},{"color":"#DAD5CC"}]},{"featureType":"administrative.country","elementType":"geometry.stroke","stylers":[{"weight":0.8},{"color":"#b16736"}]},{"featureType":"administrative","elementType":"labels","stylers":[{"weight":0.1},{"color":"#e1e1e1"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#f0ece6"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"transit","stylers":[{"visibility":"off"}]}];
	var mapConfig = [
		{center: {lat: 15.961329, lng: 106.259766}, zoom: 5},
		{center: {lat: 38.5997, lng: 51.5039 }, zoom: 2}
	];
	var listMap = null;
	var designMap = null;

	var mapElements = [];
	var designMapElements = {
		"markers": [],
		"polygons": [],
		"polylines": [],
		"provinces": [],
		"countries": [],
		"overlays": []
	}
	var infoLast;

	var mapOptions = {
		mapTypeControlOptions: {
			mapTypeIds: ['mystyle', google.maps.MapTypeId.TERRAIN]
		},
		// scrollwheel: false,
		mapTypeId: 'mystyle',
		// disableDoubleClickZoom: true,
		mapTypeControl: false,
		zoomControl: true,
		streetViewControl: false,

		center: mapConfig[1].center,
		zoom: mapConfig[1].zoom
	};

	function drawMarker(map, mkr, isListMap) {
		coord = mkr.coordinate.split(",");
		point = new google.maps.LatLng(coord[1], coord[0]);
		marker = new google.maps.Marker({
			position: point,
			title: "Vị trí"
		});

		// Info Description window on click
		info = new google.maps.InfoWindow();
		content = "<div class='infowindow-content' style='min-width: 200px; min-height: 100px'>"+  mkr.description +"</div>";
		
		marker.setMap(map);
		if(isListMap) mapElements.push(marker);
		else designMapElements.markers.push(marker);

		// Using CLOSURE Code Style
		google.maps.event.addListener(marker, 'click', (function(marker, content, info) {
			return function() {
				if(infoLast) {
					infoLast.close();
				}
				info.setContent(content);
				info.open(map, marker);
				infoLast = info;
			}
		})(marker, content, info));
	}
	function drawPolygon(map, poly, isListMap) {
		coord = [];
		// Convert String to Array
		coor = poly.coordinate;
		coor = coor.split(' ');
		for(j in coor) {
			coor[j] = coor[j].split(',');
		}

		//Add data to $coord
		for(j in coor) {
			point = new google.maps.LatLng(coor[j][1], coor[j][0]);
			coord.push(new google.maps.LatLng(coor[j][1], coor[j][0]));
		}
		polygon = new google.maps.Polygon({
			paths: coord,
			strokeColor: poly.color,
			strokeOpacity: 0.8,
			strokeWeight: 1,
			fillColor: poly.color,
			fillOpacity: 0.35
		});

		//Get Center of Polygon
		var bounds = new google.maps.LatLngBounds();
		for(i = 0; i < coord.length; i++) {
			bounds.extend(coord[i]);
		}
		polyCenter = bounds.getCenter();

		// Info Description window on click
		info = new google.maps.InfoWindow();
		content = "<div class='infowindow-content' style='min-width: 200px; min-height: 100px'>"+  poly.description +"</div>";
		
		polygon.setMap(map);
		if (isListMap) mapElements.push(polygon);
		else designMapElements.polygons.push(polygon);

		// Using CLOSURE Code Style
		google.maps.event.addListener(polygon, 'click', (function(polygon, content, info, polyCenter) {
			return function() {
				if(infoLast) {
					infoLast.close();
				}
				info.setContent(content);
				info.setPosition(polyCenter); 
				info.open(map);
				infoLast = info;
			}
		})(polygon, content, info, polyCenter));
	}
	function drawPolyline(map, line, isListMap) {
		coord = [];
		// Convert String to Array
		coor = line.coordinate;
		coor = coor.split(' ');
		for(j in coor) {
			coor[j] = coor[j].split(',');
		}

		//Add data to $coord
		for(j in coor) {
			point = new google.maps.LatLng(coor[j][1], coor[j][0]);
			coord.push(new google.maps.LatLng(coor[j][1], coor[j][0]));
		}
		polylineConfig = {
			path: coord, strokeColor: line.color,
			strokeOpacity: 0.8, strokeWeight: line.width
		}
		icons = [];
		if(line.arrow == true || line.arrow == "true") {
			var arrowSymbol = {
				path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
				strokeOpacity: 1,
			};
			iconArrow = { icon: arrowSymbol, offset: "100%" };
			icons.push(iconArrow);
		}
		if(line.style == "dashed") {
			var lineSymbol = { path: 'M 0,-1 0,1', strokeOpacity: 1, scale: 4 };
			dashLine = { icon: lineSymbol, offset: "0", repeat: '20px' };
			icons.push(dashLine);
			polylineConfig.strokeOpacity = 0.1;
		}
		polylineConfig.icons = icons;

		polyline = new google.maps.Polyline(polylineConfig);
		//Get Center of polyline
		var bounds = new google.maps.LatLngBounds();
		for(i = 0; i < coord.length; i++) {
			bounds.extend(coord[i]);
		}
		polyCenter = bounds.getCenter();

		// Info Description window on click
		info = new google.maps.InfoWindow();
		content = "<div class='infowindow-content' style='min-width: 200px; min-height: 100px'>"+  line.description +"</div>";
		
		polyline.setMap(map);
		if (isListMap) mapElements.push(polyline);
		else designMapElements.polylines.push(polyline);

		// Using CLOSURE Code Style
		google.maps.event.addListener(polyline, 'click', (function(polyline, content, info, polyCenter) {
			return function() {
				if(infoLast) {
					infoLast.close();
				}
				info.setContent(content);
				info.setPosition(polyCenter); 
				info.open(map);
				infoLast = info;
			}
		})(polyline, content, info, polyCenter));
	}
	function drawOverlay(map, ovl, isListMap) {
		sw = ovl.sw.split(',');
		ne = ovl.ne.split(',');

		var imageBounds = new google.maps.LatLngBounds(
			new google.maps.LatLng(sw[0], sw[1]),
			new google.maps.LatLng(ne[0], ne[1]));

		overlay = new google.maps.GroundOverlay(ovl.url,imageBounds);
		overlay.setMap(map);

		// Info Description window on click
		info = new google.maps.InfoWindow();
		content = "<div class='infowindow-content' style='min-width: 200px; min-height: 100px'>"+  ovl.description +"</div>";
		center = imageBounds.getCenter();

		if (isListMap) mapElements.push(overlay);
		else designMapElements.overlays.push(overlay);

		// Using CLOSURE Code Style
		google.maps.event.addListener(overlay, 'click', (function(overlay, content, info, center) {
			return function() {
				if(infoLast) {
					infoLast.close();
				}
				info.setContent(content);
				info.setPosition(center); 
				info.open(map);
				infoLast = info;
			}
		})(overlay, content, info, center));
	}

	return {
		initListMap: function() {
			listMap = new google.maps.Map(document.getElementById("list-map"),mapOptions);
			listMap.mapTypes.set('mystyle',new google.maps.StyledMapType(myStyle,{ name:'My Style'}));
			google.maps.event.addListener(listMap, 'click', function(event) {
				if(infoLast) infoLast.close();
			});
			google.maps.event.addDomListener(window, "resize", function() {
				google.maps.event.trigger(listMap, "resize");
			});
			return listMap;
		},
		initDesignMap: function() {
			designMap = new google.maps.Map(document.getElementById("design-map"),mapOptions);
			designMap.mapTypes.set('mystyle',new google.maps.StyledMapType(myStyle,{ name:'My Style'}));

			google.maps.event.addListener(designMap, 'click', function(event) {
				if(infoLast) infoLast.close();
			});
			google.maps.event.addDomListener(window, "resize", function() {
				google.maps.event.trigger(designMap, "resize");
			});

			var drawingManager = new google.maps.drawing.DrawingManager({
				// drawingMode: google.maps.drawing.OverlayType.MARKER,
				drawingControl: true,
				drawingControlOptions: {
					position: google.maps.ControlPosition.BOTTOM_RIGHT,
					drawingModes: [
						google.maps.drawing.OverlayType.POLYGON,
						google.maps.drawing.OverlayType.POLYLINE
					]
				},
				polygonOptions: {
					fillColor: '#ff9900',
					fillOpacity: 0.3,
					strokeColor: '#ff9900',
					strokeWeight: 1,
					clickable: false,
					zIndex: 1,
					editable: true
				},
				polylineOptions: {
					strokeColor: '#C0392B',
					strokeWeight: 2,
					clickable: false,
					zIndex: 1,
					editable: true
				},
				rectangleOptions: {
					fillColor: '#ff9900',
					fillOpacity: 0,
					strokeColor: '#ff9900',
					strokeWeight: 2,
					// clickable: false,
					zIndex: 1,
					draggable: true,
					editable: true
				}
				// }
			});
			drawingManager.setMap(designMap);

			img = BASE_URL + "assets/images/flag-marker.png";
			marker = new google.maps.Marker({
				position: designMap.getCenter(),
				title: 'Đánh dấu bản đồ',
				icon: img,
				draggable: true
			});
			marker.setMap(designMap);

			return {
				"map": designMap,
				"mk": marker,
				"drawer": drawingManager
			}
		},
		viewMap: function(map) {

			$("body").animate({scrollTop: $("#list-map").offset().top - 200}, "normal");

			listMap.setCenter(new google.maps.LatLng(map.center[0], map.center[1]));
			listMap.setZoom(parseInt(map.zoom));

			angular.forEach(mapElements, function(el) {
				el.setMap(null);
			});
			if(map.markers && map.markers.length > 0) {
				angular.forEach(map.markers, function(mkr) {
					drawMarker(listMap, mkr, true);
				});
			} // End marker Process

			if(map.polygons && map.polygons.length > 0) {
				angular.forEach(map.polygons, function(poly) {
					drawPolygon(listMap, poly, true);
				});								
			} // End Polygons Process

			if(map.polylines && map.polylines.length > 0) {
				angular.forEach(map.polylines, function(line)	{
					drawPolyline(listMap, line, true);
				});						
			} // End polylines Process

			if(map.grounds && map.grounds.length > 0) {
				angular.forEach(map.grounds, function(ovl)	{
					drawOverlay(listMap, ovl, true);
				});						
			} // End Overlay Process
		},
		addMapToDb: function(info) {
			$http({
				url: BASE_URL + 'dashboard_api/map/addmap',
				method: "POST",
				data: $.param({map: info}),
				headers: {'Content-Type': 'application/x-www-form-urlencoded'}
			}).success(function(data, status, header, config) {
				console.log(data);
			})
		},
		resizeMaps: function() {
			$timeout(function() {
				google.maps.event.trigger(designMap, "resize");
				google.maps.event.trigger(listMap, "resize");
			}, 200);			
		},
		addDesignMarker: function(mk) {
			drawMarker(designMap, mk, false);
		},
		addDesignPolygon: function(plg) {
			drawPolygon(designMap, plg, false);
		},
		addDesignPolyline: function(pll) {
			drawPolyline(designMap, pll, false);
		},		
		addDesignOvelay: function(ovl) {
			drawOverlay(designMap, ovl, false);
		},
		eraseElement: function(type, index) {
			switch(type) {
				case 1:
					designMapElements.markers[index].setMap(null);
					break;
				case 2:
					designMapElements.polygons[index].setMap(null);
					break;
				case 3:
					designMapElements.polylines[index].setMap(null);
					break;
				case 6:
					designMapElements.overlays[index].setMap(null);
					break;
			}
		}
	}
})
